//
//  LLDayManager.swift
//  LiLi
//
//  Created by liuzhu on 2019/1/9.
//  Copyright © 2019 liuzhu. All rights reserved.
//

import UIKit

class LLDayManager: NSObject {
    // 初始化
    static let dayManager: LLDayManager = {
        let d = LLDayManager()
        return d
    }()

    // 获取单例
    class func shareDayManager() -> LLDayManager {
        return dayManager
    }

    // 根据日期字符串创建一个day
    private func createDay(dateStr: String) -> LLDay {
        let day = LLDay()
        day.dateStr = dateStr
        let date = LLDateUtil.shareLLDateUtil().stringConvertDate(string: dateStr, dateFormat: "yyyy-MM-dd")
        let dateChinese = LLDateUtil.shareLLDateUtil().gregorianToChineseDate(gregorianDate: date)
        let yearChinese = LLDateUtil.shareLLDateUtil().getChineseYear(date: date)
        let week = LLDateUtil.shareLLDateUtil().getWeekDay(date: date)
        let actions = LLActionManager.shareActionManager().isHaveActionInTheDateStr(dateStr: dateStr)
        if actions != nil {
            day.actions = actions!
        }
        day.status = 0
        day.chineseYear = yearChinese
        day.chineseDateStr = dateChinese
        day.weekStr = String(format: "%d", week)
        day.dayStatus = dayStatus(day: day)
        return day
    }
    
    // 判断day的 状态（有主事件，有从事件，无事件。。）
    private func dayStatus(day: LLDay) -> DayStatusEnum {
        if day.dateStr == LLDateUtil.shareLLDateUtil().getCurrentYearAndMonthAndDay() {
            return DayStatusEnum.DAYSTATUS_CURRENT
        }
        if day.actions.count == 0 {
            return DayStatusEnum.DAYSTATUS_NOACTION
        }
        var mainCount = 0
        var subCount = 0
        for action in day.actions {
            if action.dateStr == day.dateStr {
                mainCount = mainCount + 1
            } else {
                subCount = subCount + 1
            }
        }
        if mainCount > 0 && subCount > 0 {
            return DayStatusEnum.DAYSTATUS_ACTION_MAIN_SUB
        } else if mainCount > 0 && subCount <= 0 {
            return DayStatusEnum.DAYSTATUS_ACTION_MAIN
        } else {
            return DayStatusEnum.DAYSTATUS_ACTION_SUB
        }
    }
    
    // 对外提供days
    func loadDays(yearAndMonth: String, finish: @escaping (_ models: [LLDay]?, _ error: Error?) -> Void) {
        // 1.生成dateStr
        var days: [LLDay] = [LLDay]()
        let dateStrList = LLDateUtil.shareLLDateUtil().getDayStrListWithMonth(yearAndMonth: yearAndMonth)
        // 2.根据dateStr去SqlLite读day
        if dateStrList == nil || dateStrList?.count == 0 {
            finish(nil, nil)
            return
        }
        for dateStr in dateStrList! {
            var day = DataManager.QueryDay(dateStr: dateStr)
            if day == nil {
                day = createDay(dateStr: dateStr)
            }else{
                let newActions = LLActionManager.shareActionManager().isHaveActionInTheDateStr(dateStr: (day?.dateStr)!)
                if newActions != nil || newActions?.count != nil{
                    day?.actions = newActions!
                }
                day?.dayStatus = dayStatus(day: day!)
            }
            days.append(day!)
        }
        // 4.封装days
        days = packDaysWithNoDay(days: days)
        finish(days, nil)
    }
    
    func loadDay(dateStr:String,finish: @escaping (_ model: LLDay?, _ isSuccess:Bool) -> Void){
        let day = DataManager.QueryDay(dateStr: dateStr)
        if day != nil {
            finish(day,true)
        }else{
            finish(nil,false)
        }
    }

    // 获取某月的所有日（包括第一周要显得的上一个月的日）
    private func packDaysWithNoDay(days: [LLDay]) -> [LLDay] {
        var temDays = days
        let day = temDays.first
        let count = Int((day?.weekStr)!)! - 1
        if count == 0 {
             return temDays
        }
        for _ in 1 ... count {
            let day = LLDay()
            day.dayStatus = DayStatusEnum.DAYSTATUS_NODATE
            temDays.insert(day, at: 0)
        }
        return temDays
    }

    public func listenAction(action: LLAction,notifiName:Notification.Name) {
        let day = updateDaydeActions(action: action, notifiName: notifiName)
        if day != nil{
            // 5.保存day到sqlLite
            let days = [day]
            DataManager.saveDays(days: days as! [LLDay]) { (isSuccess) in
                if isSuccess{
                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: LLDaysAndActionUpdatedKey), object: nil, userInfo: ["action":action,"days":days])
                    print("保存days成功")
                }else{
                    //TODO 更新数据失败
                    print("保存days失败")
                }
            }
        }
    }
    
    private func updateDaydeActions(action: LLAction, notifiName: NSNotification.Name) -> LLDay? {
        if notifiName == NSNotification.Name(rawValue: LLActionAddKey) {
            let dateStr = action.dateStr
            var day = DataManager.QueryDay(dateStr: dateStr!)
            if day != nil {
                    day!.saveAction(action: action)
                    day!.dayStatus = dayStatus(day: day!)
            } else {
                day = createDay(dateStr: dateStr!)
                day!.saveAction(action: action)
                day!.dayStatus = dayStatus(day: day!)
            }
            return day
        } else if notifiName == NSNotification.Name(rawValue: LLActionUpdateKey) {
            // 先取出以前的Day
            let day = DataManager.QueryDay(dateStr: action.dateStr!)
            if day != nil {
                 day!.saveAction(action: action)
                 day!.dayStatus = dayStatus(day: day!)
            }
            return day
        } else if notifiName == NSNotification.Name(rawValue: LLActionDeleteKey) {
            let day = DataManager.QueryDay(dateStr: action.dateStr!)
            if day != nil {
                //LLAction删除后，加载day的时候回根据actionId去查找已删除的action，查不到就不忘actions里添加了，所以就不用单独删除一次了再
                //day!.deleteAction(action: action)
                day!.dayStatus = dayStatus(day: day!)
            }
            return day
        }
        return nil
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
